package hollycrm.com.libuip.socket;

/**
 * Created by aber on 2017/1/17.
 */

import android.support.v4.util.ArrayMap;

import com.google.gson.Gson;

import java.util.Map;

import hollycrm.com.libuip.internal.Beta;

import static hollycrm.com.libuip.socket.UIPMessageID.*;

/**
 * Created by aber on 2016/12/13.
 * base uip message type
 * @version 0.2.1 we replace the Bundle to Map(ArrayMap)
 *
 * AgentType: 坐席类型
 *   1 - 普通作息 ，2 - Acd坐席， 3 -- 虚拟坐席 ，4 -- 值班坐席， 绑定PSTN设备 软电话可退出
 *   5 - 直线坐席 绑定PSTN设备 软电话一直在线  6 -- APP 坐席
 *
 * DeviceType 设备类型:
 *   1  普通内部分机，5 -ACD 坐席ID   9 - PSTN 号码
 *
 * changelog:
 * - 0.2.1 we replaces the Bundle to Map(ArrayMap in android framework library)
 * - 0.3.0 add more uip message types for supporting more features
 */
public final class UIPMessage {

    private static UIPMessage Heartbeat =new UIPMessage();
    private static UIPMessage SignIn =new UIPMessage();
    private static UIPMessage SignOut =new UIPMessage();
    private static UIPMessage AgentNotReady =new UIPMessage();
    private static UIPMessage AgentReady =new UIPMessage();
    private static UIPMessage AgentOtherWork =new UIPMessage();
    private static UIPMessage Reset = new UIPMessage();
    private static UIPMessage ChangeAgentType = new UIPMessage();



    private static UIPMessage GetCallData = new UIPMessage();


    private static UIPMessage MakeCall = new UIPMessage();
    private static UIPMessage AnswerCall = new UIPMessage();
    private static UIPMessage HangupCall = new UIPMessage();
    private static UIPMessage ClearCall = new UIPMessage();
    private static UIPMessage HolderCall = new UIPMessage();

    private static UIPMessage RetrieveCall = new UIPMessage();
    private static UIPMessage ConsultCall = new UIPMessage();
    private static UIPMessage ReconnectCall = new UIPMessage();
    private static UIPMessage TransferCall = new UIPMessage();
    private static UIPMessage ConferenceCall = new UIPMessage();

    private static UIPMessage SingleStepTransfer = new UIPMessage();
    private static UIPMessage SendDTMF = new UIPMessage();

    // 质检
    private static UIPMessage ForceAgentNotReady = new UIPMessage();
    private static UIPMessage ForceAgentReady = new UIPMessage();
    private static UIPMessage ForceAgentLogout = new UIPMessage();
    private static UIPMessage Listen = new UIPMessage();
    private static UIPMessage ForceInsert = new UIPMessage();

    private static UIPMessage SetCallData = new UIPMessage();
    private static UIPMessage SendMessage = new UIPMessage();
    private static UIPMessage SvrSubscribeTopic = new UIPMessage();
    private static UIPMessage SvrUnsubscribeTopic = new UIPMessage();
    private static UIPMessage PublishDynamicTopic = new UIPMessage();
    private static UIPMessage DestroyDynamicTopic = new UIPMessage();
    private static UIPMessage RequestMonitorInfo = new UIPMessage();


    // todo some event coming from server

    /**
     *
     * 获取 心跳消息
     * */
    public static UIPMessage getHeartbeat() {
        Heartbeat.id = Cmd_Heartbeat;
        Heartbeat.type = UIPMessageType.CTYPE_HTTPSERVER;
        SignIn.status = 0;
        return Heartbeat;
    }

    /**
     *
     * 获取签入消息
     * @param workNo 工号
     * @param deviceNo 分机号
     * @param skillDesc 技能组描述
     */
    public static UIPMessage getSignIn(String workNo,String deviceNo,String skillDesc) {
        SignIn.type = UIPMessageType.CTYPE_AGENT;
        SignIn.id = Cmd_AgentLogin; // todo
        SignIn.body.put("AgentID",workNo);
        SignIn.body.put("AgentDN",deviceNo);
        SignIn.body.put("SkillDesc",skillDesc);
        SignIn.body.put("AgentType",1);
        SignIn.body.put("DeviceType",1);
        return SignIn;
    }

    /**
     * 发布动态主题
     * @param topicType  1 私有 ,2 共享
     * @param validTimeInterval  失效超时 默认24小时  传 0
     * @param groupIDS
     * */
    public static UIPMessage getPublishDynamicTopic(
            int validTimeInterval,
            int topicType,
            String agentDN,
            String groupIDS) {

        PublishDynamicTopic.id = Cmd_PublishDynamicTopic;
        PublishDynamicTopic.type = UIPMessageType.CTYPE_AGENT;
        PublishDynamicTopic.status = 0;
        PublishDynamicTopic.body.put("TopicName","WaitNum");
        PublishDynamicTopic.body.put("AgentDN",agentDN);
        PublishDynamicTopic.body.put("TopicSQL",getSQLString(groupIDS));
        PublishDynamicTopic.body.put("TopicType",topicType);
        PublishDynamicTopic.body.put("ValidTimeInterval",validTimeInterval);

        return PublishDynamicTopic;
    }

    public static UIPMessage getRequestMonitorInfo(String groupIDS,int topicID) {
        RequestMonitorInfo.id = Cmd_RequestMonitorInfo;
        RequestMonitorInfo.type = UIPMessageType.CTYPE_AGENT;
        RequestMonitorInfo.status = 0;
        RequestMonitorInfo.body.put("TopicName","WaitNum");
        RequestMonitorInfo.body.put("TopicID",topicID);
        RequestMonitorInfo.body.put("TopicSQL",getSQLString(groupIDS));

        return RequestMonitorInfo;
    }

    /**
     *
     * 签出 消息
     * @param workNo 坐席工号
     * */
    public static UIPMessage getSignOut(String workNo) {
        SignOut.type = UIPMessageType.CTYPE_AGENT;
        SignOut.id = Cmd_AgentLogout; // todo
        SignOut.body.put("AgentID",workNo);
        return SignOut;
    }

    /**
     * get call data
     * 工号  , 分机号
     * */
    public static UIPMessage getGetCallData(String agentID,String deviceDN) {
        GetCallData.type = UIPMessageType.CTYPE_AGENT;
        GetCallData.id = Cmd_GetCallData;
        GetCallData.status = 0;
        GetCallData.body.put("AgentID",agentID);
        GetCallData.body.put("DeviceDN",deviceDN);
        return GetCallData;
    }



    /**
     * 获取外呼消息
     * @param workNo 坐席工号
     * @param deviceDN 坐席设备号码
     * @param DestDesc  目标号码.
     * @param DestType  目标号码类型  1-内线分机， 2-坐席工号，3-外线号码，4-技能组名称，5-IVR接入号码
     * @param CallingParty 可指定的主叫号码
     * */
    public static UIPMessage getMakeCall(String workNo,String deviceDN,int DestType,String DestDesc,String CallingParty) {
        MakeCall.type = UIPMessageType.CTYPE_AGENT;
        MakeCall.id = Cmd_MakeCall; // todo
        MakeCall.body.put("AgentID",workNo);
        MakeCall.body.put("DeviceDN",deviceDN);
        MakeCall.body.put("DestType",DestType);
        MakeCall.body.put("DestDesc",DestDesc);
        MakeCall.body.put("CallingParty",CallingParty);
        return MakeCall;
    }

    /**
     * 获取应答消息 IPCC 不支持
     */
    public static UIPMessage getAnswerCall(String workNo,String deviceDN) {
        AnswerCall.type = UIPMessageType.CTYPE_AGENT;
        AnswerCall.id = Cmd_AnswerCall; // todo
        AnswerCall.body.put("AgentID",workNo);
        AnswerCall.body.put("DeviceDN",deviceDN);
        return AnswerCall;
    }

    /**
     * 挂机
     * */
    public static UIPMessage getHangupCall(String workNo,String deviceDN) {
        HangupCall.type = UIPMessageType.CTYPE_AGENT;
        HangupCall.id = Cmd_HangupCall;
        HangupCall.body.put("AgentID", workNo);
        HangupCall.body.put("DeviceDN", deviceDN);
        return HangupCall;
    }

    /**
     * 示忙
     * @param workNo  坐席工号
     * */
    public static UIPMessage getAgentNotReady(String workNo) {
        AgentNotReady.id = Cmd_AgentNotReady;
        AgentNotReady.type = UIPMessageType.CTYPE_AGENT;
        AgentNotReady.body.put("AgentID",workNo);
        return AgentNotReady;
    }

    /**
     * 示闲
     * @param workNo 坐席工号
     * */
    public static UIPMessage getAgentReady(String workNo) {
        AgentReady.id = Cmd_AgentReady;
        AgentReady.type = UIPMessageType.CTYPE_AGENT;
        AgentReady.body.put("AgentID",workNo);
        return AgentReady;
    }

    /**
     *
     * 其他工作
     *
     * */
    public static UIPMessage getAgentOtherWork(String workNo,int restCode) {
        AgentOtherWork.id = Cmd_AgentOtherWork;
        AgentOtherWork.type = UIPMessageType.CTYPE_AGENT;
        AgentOtherWork.body.put("AgentID",workNo);
        AgentOtherWork.body.put("Reason",restCode);
        return AgentOtherWork;
    }

    /**
     * 重置坐席状态
     * */
    public static UIPMessage getReset(String workNo) {
        Reset.id = Cmd_AgentReset;
        Reset.type = UIPMessageType.CTYPE_AGENT;
        Reset.body.put("AgentID",workNo);
        return Reset;
    }

    /**
     * 坐席类型切换
     * @param agentType  目标坐席类型
     * @param deviceNo 坐席设备号
     * @param deviceType 设备类型
     * @param workNo 坐席工号
     * @param SrcAgentType 原坐席类型
     * */
    public static UIPMessage getChangeAgentType(
            String workNo,
            String deviceNo,
            String agentType,
            String deviceType,
            String SrcAgentType) {
        ChangeAgentType.id = Cmd_ChangeAgentType;
        ChangeAgentType.type = UIPMessageType.CTYPE_AGENT;
        ChangeAgentType.body.put("AgentID",workNo);
        ChangeAgentType.body.put("AgentDN",deviceNo);
        ChangeAgentType.body.put("AgentType",agentType);
        ChangeAgentType.body.put("DeviceType",deviceType);
        ChangeAgentType.body.put("SrcAgentType",SrcAgentType);
        return ChangeAgentType;
    }

    /**
     * 结束话路
     * @param workNo 坐席工号
     * @param deviceDN 坐席设备号码
     * */
    public static UIPMessage getClearCall(String workNo,String deviceDN) {
        ClearCall.id = Cmd_ClearCall;
        ClearCall.type = UIPMessageType.CTYPE_AGENT;
        ClearCall.body.put("AgentID",workNo);
        ClearCall.body.put("DeviceDN",deviceDN);
        return ClearCall;
    }

    /**
     * 保持
     * @param workNo 坐席工号
     * @param deviceDN 坐席设备号码
     * */
    public static UIPMessage getHolderCall (String workNo,String deviceDN) {
        HolderCall.id = Cmd_HoldCall;
        HolderCall.type = UIPMessageType.CTYPE_AGENT;
        HolderCall.body.put("AgentID",workNo);
        HolderCall.body.put("DeviceDN",deviceDN);
        return HolderCall;
    }

    /**
     * 取保持
     * @param workNo 坐席工号
     * @param deviceDN 坐席设备号码
     * */
    public static UIPMessage getRetrieveCall(String workNo,String deviceDN) {
        RetrieveCall.id = Cmd_RetrieveCall;
        RetrieveCall.type = UIPMessageType.CTYPE_AGENT;
        RetrieveCall.body.put("AgentID",workNo);
        RetrieveCall.body.put("DeviceDN",deviceDN);
        return RetrieveCall;
    }

    /**
     * 咨询
     * @param workNo 坐席工号.
     * @param deviceDN 坐席设备号码.
     * @param actionType 动作类型  0 - 不做任何附加操作，1- 会议时操作，
     *                   2 - 通话转时操作 ，3 - 振铃转时操作， 4 -单步转时操作，
     *                   5 - 发起本方咨询，6 -发起对方咨询， 7 咨询变转接
     * @param destType 设备号码类型  1- 内线分机 2-坐席工号 3- 外线号码，4 -技能组名称，5-IVR接入号码
     * @param destDesc 目标号码
     * @param callingParty 可指定的主叫号码
     * */
    public static UIPMessage getConsultCall(
            String workNo,String deviceDN,
            String destType,String destDesc,
            String actionType,String callingParty) {
        ConsultCall.id = Cmd_ConsultCall;
        ConsultCall.type = UIPMessageType.CTYPE_AGENT;
        ConsultCall.body.put("AgentID",workNo);
        ConsultCall.body.put("DeviceDN",deviceDN);
        ConsultCall.body.put("DestType",destType);
        ConsultCall.body.put("DestDesc",destDesc);
        ConsultCall.body.put("ActionType",actionType);
        ConsultCall.body.put("CallingParty",callingParty);
        return ConsultCall;
    }

    /**
     * 咨询接回
     * @param workNo 坐席号码
     * @param deviceDN 坐席设备号码
     * */
    public static UIPMessage getReconnectCall(String workNo,String deviceDN) {
        ReconnectCall.id = Cmd_ReconnectCall;
        ReconnectCall.type = UIPMessageType.CTYPE_AGENT;
        ReconnectCall.body.put("AgentID",workNo);
        ReconnectCall.body.put("DeviceDN",deviceDN);
        return ReconnectCall;
    }

    /**
     * 咨询变转接
     * @param deviceDN 坐席设备号码
     * @param workNo 坐席工号
     * @param actionType 动作类型  7- 咨询变转接
     * */
    public static UIPMessage getTransferCall(String workNo,String deviceDN, String actionType) {
        TransferCall.id = Cmd_TransferCall;
        TransferCall.type = UIPMessageType.CTYPE_AGENT;
        TransferCall.body.put("AgentID",workNo);
        TransferCall.body.put("DeviceDN",deviceDN);
        TransferCall.body.put("ActionType",actionType);
        return TransferCall;
    }

    /**
     * 咨询变会议
     * @param deviceDN 坐席设备号码
     * @param workNo 坐席工号
     * */
    public static UIPMessage getConferenceCall(String workNo,String deviceDN) {
        ConferenceCall.id = Cmd_ConferenceCall;
        ConferenceCall.type = UIPMessageType.CTYPE_AGENT;
        ConferenceCall.body.put("AgentID",workNo);
        ConferenceCall.body.put("DeviceDN",deviceDN);
        return ConferenceCall;
    }

    /**
     * 单步转移（盲转）
     * @param workNo 坐席工号
     * @param actionType 动作类型 4 - 单步转时操作
     * @param deviceDN 坐席设备号码
     * @param callingParty 可指定的主要号码*/
    public static UIPMessage getSingleStepTransfer(
            String workNo,String deviceDN,String actionType,
            String callingParty
    ) {
        SingleStepTransfer.id = Cmd_SingleStepTransfer;
        SingleStepTransfer.type = UIPMessageType.CTYPE_AGENT;
        SingleStepTransfer.body.put("AgentID",workNo);
        SingleStepTransfer.body.put("DeviceDN",deviceDN);
        SingleStepTransfer.body.put("ActionType",actionType);
        SingleStepTransfer.body.put("CallingParty",callingParty);
        return SingleStepTransfer;
    }

    /**
     * 二次拨号
     * @param workNo 坐席工号
     * @param deviceDN  坐席设备号码
     * @param sendDTMF 要发送的二次拨号号码
     * */
    public static UIPMessage getSendDTMF(String workNo,String deviceDN,String sendDTMF) {
        SendDTMF.id = Cmd_SendDTMF;
        SendDTMF.type = UIPMessageType.CTYPE_AGENT;
        SendDTMF.body.put("AgentID",workNo);
        SendDTMF.body.put("DeviceDN",deviceDN);
        SendDTMF.body.put("SendDTMFDigits",sendDTMF);
        return SendDTMF;
    }

    /**
     * 强制示忙
     * @param workNo 坐席工号
     * @param destAgentID 被强制操作对象的坐席工号
     * */
    public static UIPMessage getForceAgentNotReady(String workNo,String destAgentID) {
        ForceAgentNotReady.id = Cmd_ForceAgentNotReady;
        ForceAgentNotReady.type = UIPMessageType.CTYPE_AGENT;
        ForceAgentNotReady.body.put("AgentID",workNo);
        ForceAgentNotReady.body.put("DestAgentID",destAgentID);
        return ForceAgentNotReady;
    }

    /**
     * 强制示闲
     * @param workNo 坐席工号
     * @param destAgentID 被强制操作对象的坐席工号
     * */
    public static UIPMessage getForceAgentReady(String workNo,String destAgentID) {
        ForceAgentReady.id = Cmd_ForceAgentReady;
        ForceAgentReady.type = UIPMessageType.CTYPE_AGENT;
        ForceAgentReady.body.put("AgentID",workNo);
        ForceAgentReady.body.put("DestAgentID",destAgentID);
        return ForceAgentReady;
    }

    /**
     * 强制签出
     * @param workNo 坐席工号
     * @param destAgentID 被强制操作工号
     * */
    public static UIPMessage getForceAgentLogout(String workNo,String destAgentID) {
        ForceAgentLogout.id = Cmd_ForceAgentLogout;
        ForceAgentLogout.type = UIPMessageType.CTYPE_AGENT;
        ForceAgentLogout.body.put("AgentID",workNo);
        ForceAgentLogout.body.put("DestAgentID",destAgentID);
        return ForceAgentLogout;
    }

    /**
     * 监听
     * @param workNo 坐席工号.
     * @param deviceDN 坐席设备号 .
     * @param destType 目标号码 1- 内线分机 2- 坐席工号
     * @param destDesc 目标号码
     * */
    public static UIPMessage getListen(String workNo,String deviceDN,String destType,String destDesc) {
        Listen.id = Cmd_Listen;
        Listen.type = UIPMessageType.CTYPE_AGENT;
        Listen.body.put("AgentID",workNo);
        Listen.body.put("DeviceDN",deviceDN);
        Listen.body.put("DestType",destType);
        Listen.body.put("DestDesc",destDesc);
        return Listen;
    }

    /**
     * 强插
     * @param workNo  坐席工号
     * @param deviceDN 坐席设备号
     * @param destDesc 目标号码
     * @param destType 目标号码类型 1- 内线分机 2- 坐席工号
     * */
    public static UIPMessage getForceInsert(String workNo,String deviceDN,String destType,String destDesc) {
        ForceInsert.id = Cmd_ForceInsert;
        ForceInsert.type = UIPMessageType.CTYPE_AGENT;
        ForceInsert.body.put("AgentID",workNo);
        ForceInsert.body.put("DeviceDN",deviceDN);
        ForceInsert.body.put("DestType",destType);
        ForceInsert.body.put("DestDesc",destDesc);
        return ForceInsert;
    }

    /**
     * 设置随路数据
     * not using this method
     * */
    @Beta
    public static UIPMessage getSetCallData() {
        throw new UnsupportedOperationException("not support SetCallData message");
    }

    /**
     * 发送坐席消息
     * @param workNo 坐席工号
     * @param deviceDN 坐席设备号
     * @param messageBody 要发送的消息内容
     * @param destType 目标类型 1- 坐席工号 2- 技能组名称
     * @param destID 目标坐席工号(目标类型为1时)
     * @param destName 目标技能组名称(目标类型为2时)
     * */
    public static UIPMessage getSendMessage(
            String workNo,String deviceDN,String messageBody,
            String destType,String destID,String destName) {
        SendMessage.id = Cmd_SendMessage;
        SendMessage.type = UIPMessageType.CTYPE_AGENT;
        SendMessage.body.put("AgentID",workNo);
        SendMessage.body.put("DeviceDN",deviceDN);
        SendMessage.body.put("MessageBody",messageBody);
        SendMessage.data.put("DestType",destType);
        SendMessage.data.put("DestName",destName);
        return SendMessage;
    }

    /**
     * 订阅数据
     * @param topicID 主题ID
     * @param topicName 主题名字
     * @param topicSQL 主题对应的SQL
     * */
    public static UIPMessage getSvrSubscribeTopic(
            String topicID,String topicName,String topicSQL) {
        SvrSubscribeTopic.id = Cmd_Svr_SubscribeTopic;
        SvrSubscribeTopic.type = UIPMessageType.CTYPE_AGENT;
        SvrSubscribeTopic.body.put("TopicID",topicID);
        SvrSubscribeTopic.body.put("TopicName",topicName);
        SvrSubscribeTopic.body.put("TopicSQL",topicSQL);
        return SvrSubscribeTopic;
    }

    /**
     * 取消订阅
     * @param topicID 主题ID
     * @param topicName 主题名字
     * @param topicSQL 主题对应的SQL
     * */
    public static UIPMessage getSvrUnsubscribeTopic(
            String topicID,String topicName,String topicSQL
    ) {
        SvrUnsubscribeTopic.id = Cmd_IBaseSvr_UnsubscribeTopic;
        SvrUnsubscribeTopic.type = UIPMessageType.CTYPE_AGENT;
        SvrUnsubscribeTopic.body.put("TopicID",topicID);
        SvrUnsubscribeTopic.body.put("TopicName",topicName);
        SvrUnsubscribeTopic.body.put("TopicSQL",topicSQL);
        return SvrUnsubscribeTopic;
    }

    /**
     * 删除动态主题
     * @param topicSQL  对应主题的SQL.
     * @param topicName 主题名字.
     * @param topicID 主题ID.
     * */
    public static UIPMessage getDestroyDynamicTopic(
            String topicID,String topicName,String topicSQL) {
        DestroyDynamicTopic.id = Cmd_DestroyDynamicTopic;
        DestroyDynamicTopic.type = UIPMessageType.CTYPE_AGENT;
        DestroyDynamicTopic.body.put("TopicID",topicID);
        DestroyDynamicTopic.body.put("TopicName",topicName);
        DestroyDynamicTopic.body.put("TopicSQL",topicSQL);
        return DestroyDynamicTopic;
    }

    // todo more message type need by

    private static String getSQLString(String groupIds) {
        String[] groupIDS = groupIds.split(",");
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT t1.SkillID SkillID,t2.SkillName SkillName,t1.ContactInQueue WaitNum " +
                "FROM RT_Domain t1, RT_SkillGroup t2 WHERE t1.SkillID!=0 AND t1.SkillID=t2.SkillID AND t1.UpdateNum>0 AND (");

        for (int i = 0; i < groupIDS.length; i++) {
            sb.append(" t2.SkillName = '")
                    .append(groupIDS[i])
                    .append("' ");
            if (i != groupIDS.length - 1) {
                sb.append("OR ");
            }
        }
        sb.append(")  ORDER BY SkillID");
        return sb.toString();
    }

    public String id;

    public String type;

    public int status;

    public Map<String,Object> body;

    public Map<String,Object> data;

    private UIPMessage() {
        body = new ArrayMap<>();
        data = new ArrayMap<>();
    }

    private UIPMessage(Builder builder) {
        type = builder.type;
        id = builder.id;
        status = builder.status;
        body = builder.body;
        data = builder.data;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }

        if (obj instanceof UIPMessage) {
            UIPMessage message = (UIPMessage) obj;
            return type.equals(message.type)
                    && id.equals(message.id)
                    && (status == message.status)
                    && data.equals(message.data)
                    && body.equals(message.body);
        }
        return false;
    }

    @Override
    public String toString() {
        return "UIPMessage{" +
                "id='" + id + '\'' +
                ", type='" + type + '\'' +
                ", status=" + status +
                ", body=" + body +
                ", data=" + data +
                '}';
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static final class Builder {

        private String type;

        private String id;

        private int status;

        private Map<String,Object> body;

        private Map<String,Object> data;

        private Builder() {
            body = new ArrayMap<>();
            data = new ArrayMap<>();
        }

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

        public Builder setId(String id) {
            this.id = id;
            return this;
        }

        public Builder setStatus(int status) {
            this.status = status;
            return this;
        }

        public Builder setStringBody(String name,String value) {
            body.put(name,value);
            return this;
        }

        public Builder setIntBody(String name,int value) {
            body.put(name,value);
            return this;
        }

        public Builder setStringData(String name,String value) {
            data.put(name,value);
            return this;
        }

        public Builder setIntData(String name,int value) {
            data.put(name,value);
            return this;
        }

        public Builder setBundleData(Map<String,Object> da) {
            if (data.isEmpty()) {
                data = da;
            }else {
                data.putAll(da);
            }
            return this;
        }

        public Builder setBoolBody(String name,boolean value) {
            body.put(name,value);
            return this;
        }

        public UIPMessage build() {
            return new UIPMessage(this);
        }

    }
}
